require('dotenv').config();
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const { sequelize: db, testConnection } = require('./config/db');
const authRoutes = require('./routes/authRoutes');
const categoryRoutes = require('./routes/categoryRoutes');
const videoRoutes = require('./routes/videoRoutes');
const interactionRoutes = require('./routes/interactionRoutes');
const videoTypeRoutes = require('./routes/videoTypeRoutes');
const userRoutes = require('./routes/userRoutes');

// 创建Express应用
const app = express();

// 配置CORS
const corsOptions = {
  origin: process.env.CORS_ORIGIN || '*',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
};
app.use(cors(corsOptions));

// 安全中间件
app.use(helmet());

// 解析请求体
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 速率限制
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100, // 每个IP限制100个请求
  standardHeaders: true,
  legacyHeaders: false,
  message: { code: 429, message: '请求过于频繁，请稍后再试', data: null }
});
app.use(limiter);

// 健康检查接口
app.get('/health', (req, res) => {
  res.status(200).json({
    code: 200,
    message: '服务运行正常',
    data: {
      timestamp: new Date().toISOString(),
      service: 'bilibili-node-api'
    }
  });
});

// 注册路由
app.use('/api/auth', authRoutes);
app.use('/api/categories', categoryRoutes);
app.use('/api/videos', videoRoutes);
app.use('/api/interactions', interactionRoutes);
app.use('/api/video-types', videoTypeRoutes);
app.use('/api/users', userRoutes);

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error('错误:', err);
  
  // JWT认证错误
  if (err.name === 'UnauthorizedError') {
    return res.status(401).json({
      code: 401,
      message: '认证失败，请重新登录',
      data: null
    });
  }
  
  // 请求参数错误
  if (err.name === 'ValidationError') {
    return res.status(400).json({
      code: 400,
      message: err.message,
      data: null
    });
  }
  
  // 默认500错误
  res.status(500).json({
    code: 500,
    message: '服务器内部错误',
    data: null
  });
});

// 404处理
app.use((req, res) => {
  res.status(404).json({
    code: 404,
    message: '接口不存在',
    data: null
  });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
const { initRedis } = require('./utils/redisUtil');


async function startServer() {
  try {
    // 连接数据库
    await db.authenticate();
    console.log('数据库连接成功');
    
    // 连接数据库但不同步模型（避免键数量过多的问题）
    // await db.sync({ alter: true });
    console.log('数据库已连接，跳过模型同步（手动维护数据库结构）');
    
    // 初始化Redis连接
    try {
      await initRedis();
      console.log('Redis初始化成功');
      
      // 缓存预热 - 只有在Redis初始化成功后才导入Video模型并预热缓存
      try {
        const Video = require('./models/Video');
        const { warmupCache, startViewCountUpdateTimer } = require('./utils/redisUtil');
        await warmupCache(Video);
        console.log('缓存预热完成');
        
        // 启动观看次数更新定时器
        startViewCountUpdateTimer();
        console.log('观看次数更新定时器已启动');
      } catch (warmupError) {
        console.warn('缓存预热失败:', warmupError.message);
      }
    } catch (redisError) {
      console.warn('Redis连接失败，系统将继续运行但缓存功能不可用:', redisError.message);
    }

    
    // 启动服务器
    app.listen(PORT, () => {
      console.log(`服务器运行在 http://localhost:${PORT}`);
      console.log(`健康检查地址: http://localhost:${PORT}/health`);
      console.log(`API文档地址: http://localhost:${PORT}/api/auth`);
    });
  } catch (error) {
    console.error('启动失败:', error);
    process.exit(1);
  }
}

// 导出app和startServer函数
module.exports = {
  app,
  startServer
};

// 如果直接运行此文件，则启动服务器
if (require.main === module) {
  startServer();
}